<html>
<head><meta charset="utf-8"><title>run to completion async fn · wg-async-foundations · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/index.html">wg-async-foundations</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html">run to completion async fn</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="196035816"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/196035816" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#196035816">(May 02 2020 at 05:59)</a>:</h4>
<p><span class="user-mention" data-user-id="116009">@nikomatsakis</span> Since you asked for "small" ideas around async improvements in your latest interview post: Here is one that I started writing up a while ago, but haven't submitted as an RFC so far: <a href="https://github.com/Matthias247/rfcs/pull/1/files?short_path=36fc3ab#diff-36fc3abc58ca828473861e924cd90cf4" title="https://github.com/Matthias247/rfcs/pull/1/files?short_path=36fc3ab#diff-36fc3abc58ca828473861e924cd90cf4">https://github.com/Matthias247/rfcs/pull/1/files?short_path=36fc3ab#diff-36fc3abc58ca828473861e924cd90cf4</a></p>
<p>The idea is to have a an additional type of async functions which run to completion. Besides working more like synchronous functions, those could also abstract around completion based IO (like io_uring) without resorting to owned buffer types, and solve the "leapokalypse" issues which prevented us from offering scoped async tasks that are able to borrow data in their parent tasks scope (<a href="https://github.com/tokio-rs/tokio/issues/1879" title="https://github.com/tokio-rs/tokio/issues/1879">https://github.com/tokio-rs/tokio/issues/1879</a>). </p>
<p>I think the implementation effort might be rather small - likely smaller than any kind of async drop. But I would love to get some feedback from you and <span class="user-mention" data-user-id="116883">@tmandry</span> on the feasibility on the compiler side.</p>



<a name="196220181"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/196220181" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#196220181">(May 04 2020 at 18:23)</a>:</h4>
<p>I did indeed! But I'm not sure this qualifies as small -- I'm skimming now, but adding a new kind of future trait seems like a quite large change to me.</p>



<a name="196220288"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/196220288" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#196220288">(May 04 2020 at 18:24)</a>:</h4>
<p>(The linked text says <code>RunToCompletionFuture</code> is a type, but I think it means trait.)</p>



<a name="196228577"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/196228577" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#196228577">(May 04 2020 at 19:28)</a>:</h4>
<p>It's not minimal. But I do actually feel it's smaller than the necesssary changes that would make any kind of async drop or lifecycle traits helpful for real applications. And those had been mentioned in the blog post</p>



<a name="196230222"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/196230222" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#196230222">(May 04 2020 at 19:41)</a>:</h4>
<p>I have to respond to that users thread -- I don't quite understand the believe that the async-drop changes are so massive, though I can believe that it's not <em>useful</em></p>



<a name="196231492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/196231492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#196231492">(May 04 2020 at 19:51)</a>:</h4>
<blockquote>
<p>I don't quite understand the believe that the async-drop changes are so massive</p>
</blockquote>
<p>I think that will just depend about which part we are talking about. Maybe it's not a big change in the compiler (would it care about it at all? I don't know) -  or the standard library. But having to change every single combinator in Rusts ecosystem to make it somewhat useful is a gigantic task.</p>
<p>And for the case someone forgets to implement such a combinator, all the methods that use async drop would need to implement async drop in addition to a safe synchronous drop. That introduces additional work for every library author afterwards, and raise the question why to do it at all.</p>



<a name="196231805"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/196231805" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#196231805">(May 04 2020 at 19:53)</a>:</h4>
<p>they have to implement synchronous drop regardless, I believe</p>



<a name="196231840"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/196231840" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#196231840">(May 04 2020 at 19:53)</a>:</h4>
<p>I don't really think there's a way around that except (as you are proposing) changing the underlying model completely</p>



<a name="219657434"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/219657434" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#219657434">(Dec 11 2020 at 20:25)</a>:</h4>
<p>I'm pushing this one up, since I'm still very interested in seeing this included. I'm rather motivated by some the discussions like <a href="#narrow/stream/187312-wg-async-foundations/topic/mutex-usage">https://rust-lang.zulipchat.com/#narrow/stream/187312-wg-async-foundations/topic/mutex-usage</a> as well as <a href="https://internals.rust-lang.org/t/pre-pre-rfc-unsafe-futures/13186">https://internals.rust-lang.org/t/pre-pre-rfc-unsafe-futures/13186</a> that this is the right thing to do. </p>
<p>Just like <span class="user-mention" data-user-id="137147">@Didrik Nordstrom</span>  my experience is that most async users are not aware about the special cancellation semantics and all the nitty-gritty details of how async/await works. They just want to write code as usual, and place async annotations on it to make sure code runs on an eventloop. <code>async-trait</code> is a huge success and enabler for getting us there. But other semantic differences - like the cancellation one - still makes it tricky to convert synchronous code into asynchronous one and be assured things still work.</p>
<p>I also feel like this is a blocker to for building a good framework around structured concurrency (which was discussed in <a href="https://github.com/tokio-rs/tokio/issues/1879">https://github.com/tokio-rs/tokio/issues/1879</a> but then rejected due to issues with synchronous drop). <br>
Imho enabling structured concurrency would be huge plus for enabling more correct concurrent applications, since it avoids certain kinds of race conditions and runaway background tasks which are non concurrency limited. Swift is now also heading into this direction, which should work out fine for them due to non cancellable tasks: <a href="https://github.com/DougGregor/swift-evolution/blob/06fd6b3937f4cd2900bbaf7bb22889c46b5cb6c3/proposals/nnnn-structured-concurrency.md">https://github.com/DougGregor/swift-evolution/blob/06fd6b3937f4cd2900bbaf7bb22889c46b5cb6c3/proposals/nnnn-structured-concurrency.md</a></p>
<p><span class="user-mention" data-user-id="137147">@Didrik Nordstrom</span> , <span class="user-mention" data-user-id="116883">@tmandry</span> , <span class="user-mention" data-user-id="116009">@nikomatsakis</span> Let me please know if you are interested in this, and what the best way is go forward here. Happy to have a meeting to talk about this, before  just blindly submitting the RFC.</p>
<p>I know that on the AWS end <span class="user-mention" data-user-id="207781">@Lucio Franco</span> also might be interested to be involved in this.</p>



<a name="221376030"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/221376030" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#221376030">(Jan 02 2021 at 00:16)</a>:</h4>
<p><span class="user-mention" data-user-id="204219">@Matthias247</span> Sorry for being slow to respond here. My current thinking is that while the model we have can be surprising compared to other languages, I haven't personally seen a convincing argument that it's fundamentally flawed and we need to make a new one. Though it's possible one might exist, I'm limited in my perspective. Adding a new "function color" or type linearization would create a lot of churn and would have to be very well motivated. The biggest use case I've seen cited is completion queue / shared buffer ownership semantics, where the approach taken by ringbahn seems promising to me.</p>



<a name="221483035"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/221483035" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#221483035">(Jan 04 2021 at 02:05)</a>:</h4>
<p>Thanks for the response <span class="user-mention" data-user-id="116883">@tmandry</span> . I think "completion based IO" things are only  one part of the motivation. But in the meantime I'm actually more interested in the additional guarantees that potentially important cleanup code is really run, and in enabling structured concurrency.</p>
<p>The "Async Drop" discussion definitely showed there was more interest in the problem. And I am not sure why this model had more interest/support so far despite having far weaker guarantees and being less ergonomic than this model (where we don't need manually written futures and <code>poll_drop</code> functions - just regular code which could be a 1:1 migration of the synchronous variant).</p>
<p>Regarding data and motivation: I so far audited a couple of internal codebases using Rust + async/await ("internal" here mostly means being written by people who are not the well-known Rust async-experts). None of them had pre-cautions against tasks being forcefully cancelled, e.g by using destructors for everything -so I don't think this "feature" of async/await is well-known. These codebases also often lacked structured ways to shut down / cancel tasks. This is necessary in many production environments to prevent resource exhaustion - however I think with the current tools people simply grab for <code>task::spawn</code>, create run-away tasks and don't care about it until they hit the first production issue. To prevent this I would still like to introduce better ways to manage the lifetime of tasks overall. Structured concurrency, as available in Kotlin and now also adopted in async Swift seems like the way to go. This would also work without run to completion tasks - but static guarantees seem a lot more preferrable for most people.</p>
<p>I might also work on a survey to gather more feedback about how many people are aware about the cancellation behavior, and how they handle it.</p>



<a name="221496192"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/221496192" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#221496192">(Jan 04 2021 at 07:39)</a>:</h4>
<p>Thanks for clarifying. I do really think we need to get better at documenting this, in the async book and standard library docs to start.</p>



<a name="221496330"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/221496330" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#221496330">(Jan 04 2021 at 07:42)</a>:</h4>
<p>And perhaps that should include emphasis on patterns like RAII.</p>



<a name="221496529"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/221496529" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#221496529">(Jan 04 2021 at 07:47)</a>:</h4>
<p>I think lack of async drop is a problem we need to solve</p>



<a name="222010174"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222010174" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222010174">(Jan 07 2021 at 22:21)</a>:</h4>
<p>I read the <code>poll_drop</code> proposal and I think it's super clever to solve many problems in a backwards compatible way. Do y'all know what happens in the early return case, i.e. using <code>?</code> or other ways of short-circuiting control flow? Is <code>poll_drop</code> meant to be invoked in these cases as well?</p>



<a name="222013455"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222013455" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222013455">(Jan 07 2021 at 22:53)</a>:</h4>
<p>That said, <code>poll_drop</code> leaves the other issues unresolved. Me and Tyler talked about this recently. There are numerous issues related:</p>
<ul>
<li>scoped threads, was removed from Rust because you can create a reference cycle of join handles, which can be unsafe: <a href="https://github.com/rust-lang/rust/issues/24292">https://github.com/rust-lang/rust/issues/24292</a></li>
<li>mutex guards (even synchronous) can have their critical section interrupted in the case of early returns.</li>
</ul>
<p>Both of these issues can be mitigated with an extra closure (see <a href="https://docs.rs/crossbeam/0.8.0/crossbeam/thread/fn.scope.html">https://docs.rs/crossbeam/0.8.0/crossbeam/thread/fn.scope.html</a>). Crossbeam also provides a more general scope util: <a href="https://docs.rs/crossbeam/0.8.0/crossbeam/fn.scope.html">https://docs.rs/crossbeam/0.8.0/crossbeam/fn.scope.html</a></p>
<p>I think what we need, generally, is types that cannot be dropped implicitly -- a way to enforce that destruction is explicit and covered on every code path, except while panicking. In that case you _only_ want to clean up resources, and possibly poison some resource. But panicking is not the typical case.</p>



<a name="222013634"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222013634" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222013634">(Jan 07 2021 at 22:55)</a>:</h4>
<p>A type that must be destructed explicitly could not be inserted into an Rc/Arc - that follows naturally. It solves the scoped thread problem.</p>



<a name="222014553"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222014553" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tm <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222014553">(Jan 07 2021 at 23:04)</a>:</h4>
<p>I had quite different impression with regards to backward compatibility, and think that <code>poll_drop</code> as proposed would be significant breaking change due to extra yield points it introduces. I consider this aspect to be major unresolved issue.</p>



<a name="222019280"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222019280" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222019280">(Jan 08 2021 at 00:03)</a>:</h4>
<p><span class="user-mention" data-user-id="352985">@tm</span> Yes, but at least it only applies to manual future impls and combinators, right?</p>



<a name="222019446"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222019446" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222019446">(Jan 08 2021 at 00:05)</a>:</h4>
<p>BTW When I say _destructed explicitly_, I mean that one must use a <code>fn foo(self, ..)</code> method under normal (non-panic) circumstances. I don't have a proposal for how it would interact with <code>Drop</code>.</p>



<a name="222019520"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222019520" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tm <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222019520">(Jan 08 2021 at 00:06)</a>:</h4>
<p>It is part of Drop so it applies to everything not known to be Copy.</p>



<a name="222020434"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222020434" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tm <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222020434">(Jan 08 2021 at 00:18)</a>:</h4>
<p>In async context dropping a generic T would introduce a yield point. It is not even clear why dropping a String or Vec&lt;u8&gt; wouldn't introduce one.</p>



<a name="222020705"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222020705" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222020705">(Jan 08 2021 at 00:23)</a>:</h4>
<p><span class="user-mention silent" data-user-id="352985">tm</span> <a href="#narrow/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn/near/222014553">said</a>:</p>
<blockquote>
<p>I had quite different impression with regards to backward compatibility, and think that <code>poll_drop</code> as proposed would be significant breaking change due to extra yield points it introduces. I consider this aspect to be major unresolved issue.</p>
</blockquote>
<p>The number of yield points of an async fn shouldn't be considered stable, imo</p>



<a name="222020867"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222020867" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tm <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222020867">(Jan 08 2021 at 00:25)</a>:</h4>
<p>The presence of absence of yield points influences what becomes part of generator, and whether resulting future is Send etc.</p>



<a name="222020963"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222020963" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222020963">(Jan 08 2021 at 00:26)</a>:</h4>
<p>I see. In theory I <em>think</em> we can solve this with better analysis</p>



<a name="222020978"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222020978" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222020978">(Jan 08 2021 at 00:26)</a>:</h4>
<p>but I'll have to think about it more</p>



<a name="222021007"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222021007" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222021007">(Jan 08 2021 at 00:27)</a>:</h4>
<p>though I can see how generics would be a problem, hm</p>



<a name="222022221"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222022221" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222022221">(Jan 08 2021 at 00:45)</a>:</h4>
<p>Hmm, does this illustrate the concern?</p>
<div class="codehilite"><pre><span></span><code>async fn foo&lt;T&gt;() -&gt; bool {
  let t = T;
  true
  // implicit yield point here, so the generator must store a ref to t, which can affect sendness
}
</code></pre></div>



<a name="222026104"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222026104" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222026104">(Jan 08 2021 at 01:54)</a>:</h4>
<p>right</p>



<a name="222029363"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222029363" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222029363">(Jan 08 2021 at 02:59)</a>:</h4>
<p>found the original thread: <a href="https://github.com/rust-lang/rfcs/pull/2958#discussion_r457294076">https://github.com/rust-lang/rfcs/pull/2958#discussion_r457294076</a></p>



<a name="222040848"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222040848" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222040848">(Jan 08 2021 at 05:54)</a>:</h4>
<p>I don't think async drop necessarily had a backward compatibility problem. But it also provided zero guarantees that it actually solves any issue. If someone had any manual implemented future in their code (e.g. <code>select!</code> or just <code>FutureExt::fuse</code>), the drop feature might have been lost without anyone getting aware about it. You can't really expect every developer to remember which combinators or functions support async drop and which not.</p>
<p>This proposal avoids the issue. And it also allows proper scoped tasks (like the crossbeam ones) in the async world.</p>



<a name="222040995"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222040995" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222040995">(Jan 08 2021 at 05:58)</a>:</h4>
<p>I also don't think this proposal is less backward compatible. Every existing code will still work. New code (using  <code>async completion fn</code> or however its called) can continue to use all existing code out there. The only thing which is required is new executors which can support spawning such a function. And this shouldn't be a huge change (for a runtime like tokio it mainly means the runtime would need to block until tasks run to completion in the destructor and wait for the finish, which it partially already does since not all tasks are cancellable)</p>



<a name="222128114"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222128114" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222128114">(Jan 08 2021 at 21:26)</a>:</h4>
<p><span class="user-mention" data-user-id="204219">@Matthias247</span> I will read your proposal again. I came from a slightly different perspective -- this lack of customizable destruction in Rust has bothered me also outside of async. I wrote up a very drafty vision: <a href="https://hackmd.io/gVMh_ZC_Qcm9Y4x2D6hE-g">https://hackmd.io/gVMh_ZC_Qcm9Y4x2D6hE-g</a></p>



<a name="222132662"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222132662" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tmandry <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222132662">(Jan 08 2021 at 22:08)</a>:</h4>
<p><span class="user-mention silent" data-user-id="204219">Matthias247</span> <a href="#narrow/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn/near/222040995">said</a>:</p>
<blockquote>
<p>I also don't think this proposal is less backward compatible. Every existing code will still work. New code (using  <code>async completion fn</code> or however its called) can continue to use all existing code out there. The only thing which is required is new executors which can support spawning such a function. And this shouldn't be a huge change (for a runtime like tokio it mainly means the runtime would need to block until tasks run to completion in the destructor and wait for the finish, which it partially already does since not all tasks are cancellable)</p>
</blockquote>
<p>It would also require combinators to support it, or they wouldn't be usable from an <code>async completion</code> context, as I understand it.</p>



<a name="222139039"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222139039" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222139039">(Jan 08 2021 at 23:26)</a>:</h4>
<p>Ok, I published my comments now.</p>



<a name="222139046"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222139046" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222139046">(Jan 08 2021 at 23:26)</a>:</h4>
<p>Thanks Matthias.</p>



<a name="222139076"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222139076" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222139076">(Jan 08 2021 at 23:26)</a>:</h4>
<p>I'll paste my biggest concern here:</p>



<a name="222139091"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222139091" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222139091">(Jan 08 2021 at 23:26)</a>:</h4>
<p>Unfortunately combinators are so deeply affected that the proposal becomes infeasible in its current state:</p>
<p>Say a combinator like select: once returned from it, what happens to the unfinished future? Return to caller just like today? Who ensures the future is polled again before dropped?</p>
<p>Same for FuturesUnordered: Poll a couple of items out, but leave some inside, then drop it - compiler is none the wiser -- and the invariant is broken.</p>
<p><strong>In general: A combinator that accepts completion futures must poll all of its inner futures to completion before returning from any of its async functions. It can neither store or return any incomplete futures because then they can be arbitrarily dropped.</strong></p>
<p>Unfortunately, this gives us three bad options:</p>
<ul>
<li>Combinators disallow this - severely degrading their utility.</li>
<li>Combinators allow this, but lose most of the guarantees of this proposal</li>
<li>Drop-bombs - panic at runtime if futures and combinators are not polled to completion at drop-time.</li>
</ul>
<p>It all boils down to this existing drop-semantics we have today - whether we're in async or not. Hence, some rudimentary linear type features are necessary, as far as I can tell.</p>



<a name="222140636"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222140636" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222140636">(Jan 08 2021 at 23:51)</a>:</h4>
<p>You can see combinators from 2 angles:</p>
<ol>
<li>Combinators which exist today (there is a lot in futures-rs, which was carried over from futures 1.0)</li>
<li>Combinators which users really need in combination with run to completion functions.</li>
</ol>
<p>First of all users can continue to use all existing combinators, but not use them run to completion functions. That's ok - they can e.g. still use <code>futures::select</code> or <code>tokio::select</code> to wait on a socket and a timeout in parallel. Or on a channel. They just can't use it for combinating a completion fn with something else (like a timeout).</p>
<p>For those combinations, I see 2 major use-cases -&gt; timeouts and cancellations. Where one is a particular use-case of the other.<br>
For thus, we would have specialized new combinator, like the timeout wrapper which does graceful cancellation.</p>
<p>An improved verison of <code>FuturesUnordered</code> which is compatible with completion functions would be the structured concurrency Scope/WaitGroup/Nursery or however we call it. It allows to spawn N tasks, and when going out of scope does trigger a graceful cancellation and waits for all of them to complete. This was already implemented in <a href="https://github.com/tokio-rs/tokio/issues/1879">https://github.com/tokio-rs/tokio/issues/1879</a> and <a href="https://github.com/tokio-rs/tokio/pull/2579">https://github.com/tokio-rs/tokio/pull/2579</a> and can be easily carried over to support run to completion tasks.</p>
<p>Swift really wants to do the same now with <a href="https://github.com/DougGregor/swift-evolution/blob/structured-concurrency/proposals/nnnn-structured-concurrency.md">https://github.com/DougGregor/swift-evolution/blob/structured-concurrency/proposals/nnnn-structured-concurrency.md</a>. <code>Task.withGroup</code> is more or less just <code>FuturesUnordered</code> with run to completion tasks and graceful cancellation signalling.</p>



<a name="222141015"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222141015" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222141015">(Jan 08 2021 at 23:57)</a>:</h4>
<p>I see, yes that could work -- need to take a look at that code, but the extra scope makes it pretty unergonomic - it's a critique I have against these articficial scopes in general, not just in this case. Brb, need to go to a meeting</p>



<a name="222144241"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222144241" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222144241">(Jan 09 2021 at 00:53)</a>:</h4>
<p>Yeah, I think the scoping here is my main gripe - I think we can't predict what combinators are gonna be useful in the future, so it could be a large overhead. The scoping enforces a lexical structure -- which limits the use cases.</p>
<p>Say I want to have a task that is owned by a type - created at construction and awaited during destruction.</p>



<a name="222144313"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222144313" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222144313">(Jan 09 2021 at 00:55)</a>:</h4>
<p>Select could be used to multiplex over channels too (like in Go). The async stream next method should probably be a completion future?</p>



<a name="222144325"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222144325" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222144325">(Jan 09 2021 at 00:55)</a>:</h4>
<p>But of course, +1 on structured concurrency in general.</p>



<a name="222144333"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222144333" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222144333">(Jan 09 2021 at 00:55)</a>:</h4>
<p>And +1 on that futures should not be arbitrarily cancelled, like today.</p>



<a name="222144530"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222144530" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222144530">(Jan 09 2021 at 00:59)</a>:</h4>
<p>If you have time, please check out the draft proposal I posted for ImplicitDrop (linear type support). There's quite some overlap. My hope is that the lexical scoping boilerplate and restriction can be avoided for improved flexibility. Happy to add more examples.</p>



<a name="222151770"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222151770" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222151770">(Jan 09 2021 at 03:47)</a>:</h4>
<blockquote>
<p>Select could be used to multiplex over channels too (like in Go).</p>
</blockquote>
<p>You can already do that! And you will continue to do so. There is no need for async channels/semaphores/mutexes/etc to become completion functions. They work fine the way they currently do, and support synchronous cancellation as expected. My challenges are really more on a higher layer, like cancelling a transaction in a distributed system which still has to do some (async) cleanup work. This isn't very well supported at the moment.</p>
<blockquote>
<p>The scoping enforces a lexical structure -- which limits the use cases.</p>
</blockquote>
<p>If you are concerned about the <code>.await</code> on the scope itself - I agree its not nice. If the language offered a <code>defer</code> it could probably be avoided - but I think this is an orthogonal effort to this one. <br>
The challenge without scopes is that leaks (either via <code>std::mem::forget</code> or implicit ones) prevent memory safety purely based on destructors. That's the same reason crossbeam scoped threads work, and the old <code>std</code> scoped threads have been removed. The whole leak/mem::forget topic is a terribly complex one and has been discussed to death - therefore I don't think we should get back to it :-) </p>
<p>But I will take a look at your doc once I find some time</p>



<a name="222342495"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222342495" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222342495">(Jan 11 2021 at 19:05)</a>:</h4>
<blockquote>
<p>The whole leak/mem::forget topic is a terribly complex one and has been discussed to death - therefore I don't think we should get back to it :-)</p>
</blockquote>
<p>Heh, I know. However, I dug around in those threads and the decision was (a) in one case rushed, because of a 1.0 release and (b) there were many good arguments on both sides, and in the end the status quo won, to my understanding, <em>because</em> there weren't enough use cases. At the time you <em>could</em> argue that scoped threads were niche, perhaps... Today, with async present, that's no longer possible.</p>



<a name="222342894"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222342894" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222342894">(Jan 11 2021 at 19:08)</a>:</h4>
<p>The closure scope workaround worked only because it hijacked the entire parent thread. That won't work for async in general (is this why your scoped tasks were rejected in the end by tokio?), <em>even if we're ok with the extra closure</em>.</p>



<a name="222343533"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222343533" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222343533">(Jan 11 2021 at 19:14)</a>:</h4>
<p>I view this as important not just because futures are hard to use, but also because we can't have any shared references across tasks or threads. I don't know if you're as bothered as I am, but our code base is just full of refcounts. Arcs everywhere. Aside from the boilerplate, it's not zero-cost and its lack of a clear ownership structure is error prone -- the resulting leaks can lead to logical bugs..</p>



<a name="222655444"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/222655444" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#222655444">(Jan 13 2021 at 22:23)</a>:</h4>
<p>Changed the semantics slightly and published pre-rfc here: <a href="https://internals.rust-lang.org/t/pre-rfc-leave-auto-trait-for-reliable-destruction/13825">https://internals.rust-lang.org/t/pre-rfc-leave-auto-trait-for-reliable-destruction/13825</a></p>



<a name="223059546"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/223059546" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#223059546">(Jan 17 2021 at 19:45)</a>:</h4>
<p>Linking this here, because it's pretty cool. Kai Jewsen implemented the RFC contents via proc macros:<br>
<a href="https://github.com/Matthias247/rfcs/pull/1#issuecomment-761803914">https://github.com/Matthias247/rfcs/pull/1#issuecomment-761803914</a><br>
<a href="https://docs.rs/completion/0.1.0/completion/index.html">https://docs.rs/completion/0.1.0/completion/index.html</a></p>
<p>And it's not just the Future, it's a complete ecosystem around it (with completion async traits, IO methods, streams, etc) <span aria-label="astonished" class="emoji emoji-1f632" role="img" title="astonished">:astonished:</span></p>



<a name="223060259"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/223060259" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Matthias247 <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#223060259">(Jan 17 2021 at 20:02)</a>:</h4>
<p><span class="user-mention" data-user-id="137147">@Didrik Nordstrom</span> </p>
<blockquote>
<p>I don't know if you're as bothered as I am, but our code base is just full of refcounts. Arcs everywhere. Aside from the boilerplate, it's not zero-cost and its lack of a clear ownership structure is error prone -- the resulting leaks can lead to logical bugs..</p>
</blockquote>
<p>It definitely happens with the current model. Even if they are not directly visible, they might be in the library types (e.g. FD handles, channels, timer handles, etc). I'm however only half worried about them being refcounts in general, and a bit more wary about the requirement for atomic refcounts everywhere since single-threaded (non-synchronized) <code>Future</code>s are not exactly the preferred and easy way. But that's a different story than this one :-) </p>
<p>I will comment on the internals thread regarding your RFC. Overall I feel like it's wider and more general change, which comes with the usual challenges of these types of changes:</p>
<ul>
<li>It might be harder to understand on how it works and it can be used for the average user</li>
<li>It's harder to predict whether it solves a specific problem very well. In this case I e.g. can't yet see how it solves <code>TaskGroup</code>s , since <code>panic!</code>s  are not yet covered.</li>
</ul>



<a name="223169889"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/223169889" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#223169889">(Jan 18 2021 at 22:37)</a>:</h4>
<p>Yeah, the atomics worry me too. But even without atomics, refcounts invalidates the cache lines.</p>



<a name="223169963"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/223169963" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#223169963">(Jan 18 2021 at 22:39)</a>:</h4>
<p>Thanks for the feedback on the pre-RFC. My focus now is to drive it to its best possible state. Once we have reviewed all relevant proposals, we could start a collaborative summary doc and involve a wider audience.</p>



<a name="223170054"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187312-wg-async-foundations/topic/run%20to%20completion%20async%20fn/near/223170054" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Didrik Nordstrom <a href="https://rust-lang.github.io/zulip_archive/stream/187312-wg-async-foundations/topic/run.20to.20completion.20async.20fn.html#223170054">(Jan 18 2021 at 22:40)</a>:</h4>
<p>The panic-unwind issues were introducing a lot of complexity indeed. Just updated the proposal. Now, panics work as usual.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>